#include <iostream>
#include <memory>
#include <vector>
#include <string>
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <pwd.h>

#include "databaseManager.h"

using namespace std;


vector<string> get_animals_list() {
    vector<string> animals;
    unique_ptr<FILE, decltype(&pclose)> pipe(popen("cowsay -l", "r"), pclose);

    if (!pipe) {
        throw runtime_error("Failed to run cowsay command");
    }

    char buffer[128];
    string output;

    while (fgets(buffer, sizeof(buffer), pipe.get()) != nullptr) {
        output += buffer;
    }

    size_t colon_pos = output.find(':');
    if (colon_pos == string::npos) {
        return {"cow", "dragon", "koala"}; // Default animals
    }

    istringstream iss(output.substr(colon_pos + 1));
    string animal;

    while (iss >> animal) {
        if (animal.length() >= 2) {
            animals.push_back(std::move(animal));
        }
    }

    return !animals.empty() ? animals : vector<string>{"cow", "dragon", "koala"};
}

void greet(const string &animal) {
    string cmd = "fortune | cowsay -f " + animal + " | lolcat";
    system(cmd.c_str());

    auto *pw = getpwuid(getuid());
    string username = pw ? pw->pw_name : "user";

    cmd = "echo '" + animal + ": Hello, " + username + "!' | lolcat";
    system(cmd.c_str());
}

string get_tty_name() {
    char *tty = ttyname(0);
    return (tty && !strstr(tty, " ")) ? tty : "/dev/pts/0";
}

int main() {
    try {
        string tty_name = get_tty_name();
        //获取当前用户主目录
        string home_dir = getenv("HOME");
        string dbPath;
        dbPath = home_dir + "/.local/share/greetings/";

        DatabaseManager db(dbPath, "tty_login.db");
        int login_count = db.update_login_count(tty_name);

        auto animals = get_animals_list();
        if (animals.empty()) {
            cerr << "No animals available, using default\n";
            animals = {"cow", "dragon", "koala"};
        }

        greet(animals[login_count % animals.size()]);
    }
    catch (const exception &e) {
        cerr << "Error: " << e.what() << endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}